﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Kay.Communication.Framework.Custom_EventArgs;

namespace Kay.Communication.Framework
{
    /// <summary>
    /// Tcp 类型的服务端
    /// </summary>
    public class TcpInterNetworkStreamServer
    {
        /// <summary>
        /// 基础通信服务端
        /// </summary>
        private BaseCommunication Server { get; set; }

        /// <summary>
        /// 通信使用的参数信息
        /// </summary>
        public CommunicationArgs CommunicationArgs { get; private set; }

        /// <summary>
        /// 获取联系人列表
        /// </summary>
        public List<ContactsInfo> Users { get { return Server == null ? null : Server.Contacts; } }

        /// <summary>
        /// 初始化 Tcp 类型的服务端
        /// </summary>
        /// <param name="port">监听端口号</param>
        public TcpInterNetworkStreamServer(ushort port)
        {
            Server = new BaseCommunication();
            CommunicationArgs = new CommunicationArgs
            {
                Encoding = Encoding.UTF8,
                AddressFamily = AddressFamily.InterNetwork,
                EndPoint = new IPEndPoint(IPAddress.Any, port),
                MessageLength = 1024 * 1000,
                ProtocolType = ProtocolType.Tcp,
                CommunicationMode = CommunicationModes.TcpServer,
                SocketType = SocketType.Stream,
                Waiting = 10000
            };
            Server.InitializeBaseCommunication(CommunicationArgs);
            Server.ContactsInfoReceived += OnServerContactsInfoReceived;
            Server.IsRuningChanged += OnServerIsRuningChanged;
            Server.ContactsConnected += OnServerContactsConnected;
            Server.ContactsOffline += OnServerContactsOffline;
            //Server.TextMessageReceived += OnServerTextMessageReceived;
            //Server.RequestSendFile += OnServerRequestSendFile;
            //Server.AgreeReceiveFile += OnServerAgreeReciveFile;
            //Server.BroadcastTextMessageReceived += OnServerBroadcastTextMessageReceived;
        }

        private void OnServerBroadcastTextMessageReceived(object sender, TextMessageReceivedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void OnServerAgreeReciveFile(object sender, FileMessageReceivedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        private void OnServerRequestSendFile(object sender, FileMessageReceivedEventArgs e)
        {
            //if (e.TransferFileInfo.SourceFileName == null)
            //{
            //    e.TransferFileInfo.Agree = false;
            //    Server.SendAgreeReceiveFileMessage(e.UserInfo.Id, null, e.TransferFileInfo);
            //    return;
            //}
            //if (RequestSendFile != null)
            //{
            //    if (RequestSendFile.Invoke(this, e))
            //    {
            //        var transferFileClientId = Helpers.GetGuidToN();
            //        e.TransferFileInfo.ReceiveId = transferFileClientId;
            //        TransferFileInfos.Add(e.TransferFileInfo);

            //        ThreadPool.QueueUserWorkItem(CreateTransferFileClientForRecive, transferFileClientId);
            //    }
            //    else
            //    {
            //        e.TransferFileInfo.Agree = false;
            //        Client.SendAgreeReceiveFileMessage(e.UserInfo.Id, OwnUserInfo.Id, e.TransferFileInfo);
            //    }
            //}
        }

        private void OnServerTextMessageReceived(object sender, TextMessageReceivedEventArgs e)
        {
            TextMessageReceived?.Invoke(this, e);
        }

        private void OnServerContactsOffline(object sender, ContactsInfoEventArgs e)
        {
            if (UserOffline != null)
                UserOffline.Invoke(this, e);
        }

        private void OnServerContactsConnected(object sender, ContactsInfoEventArgs e)
        {
            UserOnline?.Invoke(this, e);
        }

        private void OnServerIsRuningChanged(bool obj)
        {
            if (IsRuningChanged != null)
            {
                IsRuningChanged.Invoke(obj);
            }
        }

        private bool OnServerContactsInfoReceived(object sender, ContactsInfoEventArgs e)
        {
            // 如果需要验证用户信息，从这里进行验证
            return true;
        }

        /// <summary>
        /// 启动服务端
        /// </summary>
        public void Start()
        {
            Server.Listening();
        }

        /// <summary>
        /// 停止服务端
        /// </summary>
        public void Stop()
        {
            Server.Close();
            Server.InitializeBaseCommunication(CommunicationArgs);
        }

        /// <summary>
        /// 关闭指定客户端
        /// </summary>
        /// <param name="id">客户端 Id</param>
        public void CloseClient(string id)
        {
            Server.DisconnectClient(id);
        }

        /// <summary>
        /// 运行状态改变事件
        /// </summary>
        [Description("当运行状态改变时发生")]
        public event Action<bool> IsRuningChanged;

        /// <summary>
        /// 用户上线事件
        /// </summary>
        [Description("当有新用户上线时发生")]
        public event EventHandler<ContactsInfoEventArgs> UserOnline;

        /// <summary>
        /// 用户下线事件
        /// </summary>
        [Description("当有新用户下线时发生")]
        public event EventHandler<ContactsInfoEventArgs> UserOffline;

        /// <summary>
        /// 收到文本消息事件
        /// </summary>
        [Description("当收到文本消息时发生")]
        public event EventHandler<TextMessageReceivedEventArgs> TextMessageReceived;

        /// <summary>
        /// 请求发送文件事件
        /// </summary>
        [Description("当收到请求发送文件时发生")]
        public event EventHandler<FileMessageReceivedEventArgs, bool> RequestSendFile;
    }
}